package com.custom.action.joiner.interfaces;

import com.custom.comm.utils.lambda.SFunction;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 表连接-一般条件
 * @author Xiao-Bai
 * @since 2023/4/30 11:52
 */
public interface JoinCondition<Result> extends Serializable {

    <Any> Result eq(boolean condition, SFunction<Any,?> column, Object val);
    default <Any> Result eq(SFunction<Any,?> column, Object val) {
        return eq(true, column, val);
    }

    <Any> Result ne(boolean condition, SFunction<Any,?> column, Object val);
    default <Any> Result ne(SFunction<Any,?> column, Object val) {
        return ne(true, column, val);
    }

    <Any> Result ge(boolean condition, SFunction<Any,?> column, Object val);
    default <Any> Result ge(SFunction<Any,?> column, Object val) {
        return ge(true, column, val);
    }

    <Any> Result le(boolean condition, SFunction<Any,?> column, Object val);
    default <Any> Result le(SFunction<Any,?> column, Object val) {
        return le(true, column, val);
    }

    <Any> Result lt(boolean condition, SFunction<Any,?> column, Object val);
    default <Any> Result lt(SFunction<Any,?> column, Object val) {
        return lt(true, column, val);
    }

    <Any> Result gt(boolean condition, SFunction<Any,?> column, Object val);
    default <Any> Result gt(SFunction<Any,?> column, Object val) {
        return gt(true, column, val);
    }

    <Any> Result in(boolean condition, SFunction<Any,?> column, Collection<?> val);
    default <Any> Result in(SFunction<Any,?> column, Collection<?> val) {
        return in(true, column, val);
    }

    default <Any> Result in(boolean condition, SFunction<Any,?> column, Object... values) {
        return in(condition, column,
                Arrays.stream(Optional.ofNullable(values).orElseGet(() -> new Object[]{}))
                        .collect(Collectors.toList())
        );
    }
    default <Any> Result in(SFunction<Any,?> column, Object... values) {
        return in(true, column, values);
    }

    <Any> Result inSql(boolean condition, SFunction<Any,?> column, String inSql, Object... params);
    default <Any> Result inSql(SFunction<Any,?> column, String inSql, Object... params) {
        return inSql(true, column, inSql, params);
    }

    <Any> Result notIn(boolean condition, SFunction<Any,?> column, Collection<?> val);
    default <Any> Result notIn(SFunction<Any,?> column, Collection<?> val) {
        return notIn(true, column, val);
    }

    <Any> Result notInSql(boolean condition, SFunction<Any,?> column, String inSql, Object... params);
    default <Any> Result notInSql(SFunction<Any,?> column, String inSql, Object... params) {
        return notInSql(true, column, inSql, params);
    }

    Result exists(boolean condition, String existsSql);
    default Result exists(String existsSql) {
        return exists(true, existsSql);
    }

    Result notExists(boolean condition, String notExistsSql);
    default Result notExists(String notExistsSql) {
        return notExists(true, notExistsSql);
    }

    <Any> Result like(boolean condition, SFunction<Any,?> column, Object val);
    default <Any> Result like(SFunction<Any,?> column, Object val) {
        return like(true, column, val);
    }

    <Any> Result notLike(boolean condition, SFunction<Any,?> column, Object val);
    default <Any> Result notLike(SFunction<Any,?> column, Object val) {
        return notLike(true, column, val);
    }

    <Any> Result likeLeft(boolean condition, SFunction<Any,?> column, Object val);
    default <Any> Result likeLeft(SFunction<Any,?> column, Object val) {
        return likeLeft(true, column, val);
    }

    <Any> Result likeRight(boolean condition, SFunction<Any,?> column, Object val);
    default <Any> Result likeRight(SFunction<Any,?> column, Object val) {
        return likeRight(true, column, val);
    }

    <Any> Result between(boolean condition, SFunction<Any,?> column, Object val1, Object val2);
    default <Any> Result between(SFunction<Any,?> column, Object val1, Object val2) {
        return between(true, column, val1, val2);
    }

    <Any> Result notBetween(boolean condition, SFunction<Any,?> column, Object val1, Object val2);
    default <Any> Result notBetween(SFunction<Any,?> column, Object val1, Object val2) {
        return notBetween(true, column, val1, val2);
    }

    <Any> Result isNull(boolean condition, SFunction<Any,?> column);
    default <Any> Result isNull(SFunction<Any,?> column) {
        return isNull(true, column);
    }

    <Any> Result isNotNull(boolean condition, SFunction<Any,?> column);
    default <Any> Result isNotNull(SFunction<Any,?> column) {
        return isNotNull(true, column);
    }

}
